<?php

namespace App\Recharge\Logic;

use Ramsey\Uuid\Uuid;
use App\Models\Mysql\CycleOrder;
use App\Models\Mysql\CyclePercentage;
use App\Models\Mysql\XnSupplierGoods;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;

/**
 * 循环冲逻辑层
 */
class CycleLogic extends BaseLogic
{
    /**
     * 获取主商品
     *
     * @param int $gid 商品id
     * @param int $goods_belong
     * @return Builder|XnSupplierGoods|null
     */
    public function mainProduct(int $gid, int $goods_belong): XnSupplierGoods|Builder|null
    {
        return XnSupplierGoods::s($this->supplier)
            ->where('id', $gid)
            ->where('goods_belong', $goods_belong)
            ->where('is_up', 1)
            ->where('release', 1)
            ->orderByDesc('id')
            ->first();
    }

    /**
     * 根据状态获取循环冲订单
     *
     * @param string $order_no 订单号
     * @param int $state 状态
     * @return Builder|CycleOrder|null
     */
    public function cycleOrderBysState(string $order_no, int $state = 0): Builder|CycleOrder|null
    {
        return CycleOrder::s($this->supplier)->where(compact('order_no', 'state'))->first();
    }

    /**
     * 获取因为峰值失败的订单
     *
     * @param XnSupplierGoods $good 主商品
     * @param string $order_no 订单号
     * @return Collection
     */
    public function peakFailureCycleOrder(XnSupplierGoods $good, string $order_no): Collection
    {
        return $good
            ->eachOrderChildren($order_no)
            ->where('peak_failure', 1)
            ->where('state', 2)
            ->get();
    }

    /**
     * @param string $order_no
     * @return int
     */
    public function countCycleByOrderNum(string $order_no): int
    {
        return CycleOrder::s($this->supplier) ->where('order_no', $order_no)->count();
    }

    /**
     * 峰值统计已经成功的单子数
     *
     * @param CycleOrder $order 循环订单
     * @return int
     */
    public function countSimilarOrders(CycleOrder $order): int
    {
        return CycleOrder::s($this->supplier)
            ->where('order_no', $order->order_no)
            ->where('gid', $order->gid)
            ->where('pid', $order->pid)
            ->where('peak_failure', 2)
            ->count();
    }

    /**
     * 查询
     *
     * @param string $order_no 订单号
     * @param int $gid 主商品id
     * @return Builder|CycleOrder|null
     */
    public function getCycleOrderByGid(string $order_no, int $gid): Builder|CycleOrder|null
    {
        return CycleOrder::s($this->supplier)
            ->where(compact('order_no', 'gid'))
            ->orderByDesc('id')
            ->first();
    }

    /**
     * 获取最后的一个uuid
     *
     * @param int $pid 主商品id
     * @param int $percentageSingular 循环最大数
     * @return array
     */
    function percentageLastUuid(int $pid, int $percentageSingular = 10): array
    {
        $row = CyclePercentage::s($this->supplier)
            ->where('pid', $pid)
            ->groupBy('uuid')
            ->orderByDesc('id')
            ->limit(1)
            ->selectRaw('uuid,count( "id" ) AS num')
            ->first();
        if (!$row) {
            return ['uuid' => Uuid::uuid7()->toString(), 'num' => 0];
        }
        $row = $row->toArray();
        return $row['num'] >= $percentageSingular ? ['uuid' => Uuid::uuid7()->toString(), 'num' => 0] : $row;
    }

    /**
     * 获取当前uuid下已经走了几单了这个子商品
     *
     * @param string $uuid uuid
     * @param int $pid 主商品id
     * @param int $gid 子商品id
     * @return int
     */
    function percentageChildCount(string $uuid, int $pid, int $gid): int
    {
        return CyclePercentage::s($this->supplier)
            ->where('uuid', $uuid)
            ->where('pid', $pid)
            ->where('gid', $gid)
            ->count();
    }

    /**
     * @param string $uuid uuid
     * @param int $pid 主商品id
     * @param int $gid 子商品id
     * @param string $order_no 订单号
     * @return void
     */
    function pushPercentage(string $uuid, int $pid, int $gid, string $order_no): void
    {
        $row = new CyclePercentage();
        $row->uuid = $uuid;
        $row->gid = $gid;
        $row->pid = $pid;
        $row->order_no = $order_no;
        $row->save();
    }

    /**
     * 将充值中的转换为失败
     *
     * @param string $value 订单号
     * @param string $errorMessage 错误信息
     * @param string $key 订单号key
     * @return int
     */
    function convertingFromRechargeToFailedByOrderNo(string $value, string $errorMessage, string $key = 'order_no'): int
    {
        return CycleOrder::s($this->supplier)
            ->where($key, $value)
            ->update(['state' => 2, 'error_msg' => $errorMessage, 'error_time' => time()]);
    }
}
